﻿using System;
using System.Collections.Generic;
using System.Text;
using Demo.Controllers;
using System.IO;
using yq.IBase.DBHelper;
using System.Threading;
using System.Threading.Tasks;
using System.Data;
using yq.IBase.Basis;
using yq.IBase;
using yq.Business;
using cn.Util;
using yq.Model.Logic;
using yq.CacheHelp;
using ClassLibrary1;
using System.Linq.Expressions;
using System.Reflection;
using ConsoleApplication1.Model;
namespace ConsoleApplication1
{

    public class DynamicMethodExecutor
    {
        private Func<object, object[], object> m_execute;

        public DynamicMethodExecutor(MethodInfo methodInfo)
        {
            this.m_execute = this.GetExecuteDelegate(methodInfo);
        }

        public object Execute(object instance, object[] parameters)
        {
            return this.m_execute(instance, parameters);
        }

        private Func<object, object[], object> GetExecuteDelegate(MethodInfo methodInfo)
        {
            // parameters to execute
            ParameterExpression instanceParameter =
                Expression.Parameter(typeof(object), "instance");
            ParameterExpression parametersParameter =
                Expression.Parameter(typeof(object[]), "parameters");

            // build parameter list
            List<Expression> parameterExpressions = new List<Expression>();
            ParameterInfo[] paramInfos = methodInfo.GetParameters();
            for (int i = 0; i < paramInfos.Length; i++)
            {
                // (Ti)parameters[i]
                BinaryExpression valueObj = Expression.ArrayIndex(
                    parametersParameter, Expression.Constant(i));
                UnaryExpression valueCast = Expression.Convert(
                    valueObj, paramInfos[i].ParameterType);

                parameterExpressions.Add(valueCast);
            }

            // non-instance for static method, or ((TInstance)instance)
            Expression instanceCast = methodInfo.IsStatic ? null :
                Expression.Convert(instanceParameter, methodInfo.ReflectedType);

            // static invoke or ((TInstance)instance).Method
            MethodCallExpression methodCall = Expression.Call(
                instanceCast, methodInfo, parameterExpressions);

            // ((TInstance)instance).Method((T0)parameters[0], (T1)parameters[1], ...)
            if (methodCall.Type == typeof(void))
            {
                Expression<Action<object, object[]>> lambda =
                    Expression.Lambda<Action<object, object[]>>(
                        methodCall, instanceParameter, parametersParameter);

                Action<object, object[]> execute = lambda.Compile();
                return (instance, parameters) =>
                {
                    execute(instance, parameters);
                    return null;
                };
            }
            else
            {
                UnaryExpression castMethodCall = Expression.Convert(
                    methodCall, typeof(object));
                Expression<Func<object, object[], object>> lambda =
                    Expression.Lambda<Func<object, object[], object>>(
                        castMethodCall, instanceParameter, parametersParameter);

                return lambda.Compile();
            }
        }
    }


    class Program
    {

     

        static void Main(string[] args)
        {
            var d1 = new IListLog().GetListAll();
            Func<DbHelper, CaCheRefresh, string> doFun1 = (cn, CaChe) =>
            {
                LogUser log = new LogUser()
                {
                    LogId = "22",
                    Ip = "2",
                    LogTime = DateTime.UtcNow,
                    UserId = "2",
                    Other = "1"
                };

                new LogUserDal().Add(log, cn);
                return "";
            };

            DbExec.DoTrans(doFun1);


           var d= new IListLog().GetListAll();

           
            return;
        

            //var type = typeof(LogUser);
            //var p = type.GetProperty("LogId");
            ////lambda的参数u 
            //var param_obj = Expression.Parameter(typeof(object), "obj");
            ////类型转换
            //var convert_obj = Expression.Convert(param_obj, type);
            ////lambda的方法体 ((User)obj).Age
            //var pGetter = Expression.Property(convert_obj, p);
            ////对返回值进行类型转换
            //var returnObj = Expression.Convert(pGetter, typeof(object));
            ////编译lambda 
            //var getAge = Expression.Lambda<Func<object, object>>(returnObj, param_obj).Compile();

            //var d1= getAge(d);

            for (; ; )
            {
               

                Action ac = () =>
                {
                    yq.GetService.Create<Itool>().add(1,1);
                };

                CodeTime.RunTime(ac
                         , 0, "test0");


                Action aca = () =>
                {
                    yq.GetService.Create<Itool>().add(1,1);
                };

                CodeTime.RunTime(aca
                         , 0, "test1");


         


           



                Console.ReadLine();
            }
        }





    }
}
